package com.gzc.just.play.last.war.sceneserver.skill;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 技能基础类
 * 
 * 对应C++ SSSkill
 * 
 * @author AI Assistant
 * @version 1.0.0
 * @since 2025-11-22
 */
public class Skill {
    
    private static final Logger log = LoggerFactory.getLogger(Skill.class);
    // 技能信息
    private int skillId;                // 技能ID
    private String skillName;           // 技能名称
    private SkillType skillType;        // 技能类型
    private int skillLevel;             // 技能等级
    
    // 消耗
    private int manaCost;               // 魔力消耗
    private int goldCost;               // 金币消耗（技能使用时消耗）
    
    // 冷却
    private long cooldownTime;          // 冷却时间（毫秒）
    private long lastCastTime;          // 最后释放时间
    
    // 伤害参数
    private float damageMultiplier;     // 伤害倍率（相对攻击力）
    private int baseDamage;             // 基础伤害
    private float damageIncreaseRate;   // 伤害增长率（每级增长）
    
    // 范围
    private float castRange;            // 施法范围
    private float effectRange;          // 效果范围（AOE时使用）
    
    // 目标
    private int maxTargets;             // 最多目标数（-1表示无限制）
    private boolean targetEnemy;        // 是否可以目标敌方
    private boolean targetAlly;         // 是否可以目标友方
    private boolean targetSelf;         // 是否可以目标自己
    
    // 效果
    private String effectDescription;   // 效果描述
    private int effectDuration;         // 效果持续时间（毫秒）
    private boolean interruptible;      // 是否可被中断
    
    // 标志
    private boolean available;          // 是否可用
    private boolean enabled;            // 是否启用

    /**
     * 构造函数
     */
    public Skill(int skillId, String skillName, SkillType skillType, int skillLevel) {
        this.skillId = skillId;
        this.skillName = skillName;
        this.skillType = skillType;
        this.skillLevel = skillLevel;
        
        this.manaCost = 0;
        this.goldCost = 0;
        this.cooldownTime = 0;
        this.lastCastTime = 0;
        
        this.damageMultiplier = 1.0f;
        this.baseDamage = 0;
        this.damageIncreaseRate = 0.1f;
        
        this.castRange = 100;
        this.effectRange = 50;
        
        this.maxTargets = 1;
        this.targetEnemy = true;
        this.targetAlly = false;
        this.targetSelf = false;
        
        this.effectDescription = "";
        this.effectDuration = 0;
        this.interruptible = true;
        
        this.available = true;
        this.enabled = true;
    }

    /**
     * 检查技能是否可以释放
     */
    public boolean canCast(long currentTime, int currentMana) {
        if (!available || !enabled) {
            return false;
        }

        // 检查冷却
        if (currentTime - lastCastTime < cooldownTime) {
            return false;
        }

        // 检查魔力
        if (currentMana < manaCost) {
            return false;
        }

        return true;
    }

    /**
     * 获取剩余冷却时间
     */
    public long getRemainingCooldown(long currentTime) {
        long elapsed = currentTime - lastCastTime;
        if (elapsed >= cooldownTime) {
            return 0;
        }
        return cooldownTime - elapsed;
    }

    /**
     * 是否在冷却中
     */
    public boolean isInCooldown(long currentTime) {
        return getRemainingCooldown(currentTime) > 0;
    }

    /**
     * 释放技能
     */
    public void cast(long currentTime) {
        this.lastCastTime = currentTime;
        log.debug("技能 {} 已释放，冷却时间: {}ms", skillName, cooldownTime);
    }

    /**
     * 重置冷却
     */
    public void resetCooldown() {
        this.lastCastTime = 0;
        log.debug("技能 {} 冷却已重置", skillName);
    }

    /**
     * 获取计算后的伤害
     */
    public int calculateDamage(double attackPower) {
        return (int)(baseDamage + attackPower * damageMultiplier);
    }

    /**
     * 升级技能
     */
    public void upgrade() {
        skillLevel++;
        baseDamage = (int)(baseDamage + baseDamage * damageIncreaseRate);
        manaCost = (int)(manaCost * 1.05);
        log.info("技能 {} 已升级到 {} 级，基础伤害: {}, 魔力消耗: {}", 
                skillName, skillLevel, baseDamage, manaCost);
    }

    /**
     * 升级技能（带升级数量）
     */
    public void upgradeSkill(int levelUp) {
        for (int i = 0; i < levelUp; i++) {
            upgrade();
        }
    }

    /**
     * 更新技能冷却
     */
    public void updateCooldown(long currentTime) {
        this.lastCastTime = currentTime;
    }

    /**
     * 获取技能名称（getter）
     */
    public String getName() {
        return skillName;
    }

    /**
     * 获取技能信息字符串
     */
    public String getInfoString() {
        return String.format("技能{id=%d, 名称=%s, 类型=%s, 等级=%d, 伤害倍率=%.2f, 冷却=%dms, 魔力消耗=%d}",
                skillId, skillName, skillType.getName(), skillLevel, damageMultiplier, cooldownTime, manaCost);
    }

    @Override
    public String toString() {
        return getInfoString();
    }
    
    // ==================== Getter和Setter方法 ====================
    
    public int getSkillId() {
        return skillId;
    }
    
    public void setSkillId(int skillId) {
        this.skillId = skillId;
    }
    
    public String getSkillName() {
        return skillName;
    }
    
    public void setSkillName(String skillName) {
        this.skillName = skillName;
    }
    
    public SkillType getSkillType() {
        return skillType;
    }
    
    public void setSkillType(SkillType skillType) {
        this.skillType = skillType;
    }
    
    public int getSkillLevel() {
        return skillLevel;
    }
    
    public void setSkillLevel(int skillLevel) {
        this.skillLevel = skillLevel;
    }
    
    public int getManaCost() {
        return manaCost;
    }
    
    public void setManaCost(int manaCost) {
        this.manaCost = manaCost;
    }
    
    public int getGoldCost() {
        return goldCost;
    }
    
    public void setGoldCost(int goldCost) {
        this.goldCost = goldCost;
    }
    
    public long getCooldownTime() {
        return cooldownTime;
    }
    
    public void setCooldownTime(long cooldownTime) {
        this.cooldownTime = cooldownTime;
    }
    
    public long getLastCastTime() {
        return lastCastTime;
    }
    
    public void setLastCastTime(long lastCastTime) {
        this.lastCastTime = lastCastTime;
    }
    
    public float getDamageMultiplier() {
        return damageMultiplier;
    }
    
    public void setDamageMultiplier(float damageMultiplier) {
        this.damageMultiplier = damageMultiplier;
    }
    
    public int getBaseDamage() {
        return baseDamage;
    }
    
    public void setBaseDamage(int baseDamage) {
        this.baseDamage = baseDamage;
    }
    
    public float getDamageIncreaseRate() {
        return damageIncreaseRate;
    }
    
    public void setDamageIncreaseRate(float damageIncreaseRate) {
        this.damageIncreaseRate = damageIncreaseRate;
    }
    
    public float getCastRange() {
        return castRange;
    }
    
    public void setCastRange(float castRange) {
        this.castRange = castRange;
    }
    
    public float getEffectRange() {
        return effectRange;
    }
    
    public void setEffectRange(float effectRange) {
        this.effectRange = effectRange;
    }
    
    public int getMaxTargets() {
        return maxTargets;
    }
    
    public void setMaxTargets(int maxTargets) {
        this.maxTargets = maxTargets;
    }
    
    public boolean isTargetEnemy() {
        return targetEnemy;
    }
    
    public void setTargetEnemy(boolean targetEnemy) {
        this.targetEnemy = targetEnemy;
    }
    
    public boolean isTargetAlly() {
        return targetAlly;
    }
    
    public void setTargetAlly(boolean targetAlly) {
        this.targetAlly = targetAlly;
    }
    
    public boolean isTargetSelf() {
        return targetSelf;
    }
    
    public void setTargetSelf(boolean targetSelf) {
        this.targetSelf = targetSelf;
    }
    
    public String getEffectDescription() {
        return effectDescription;
    }
    
    public void setEffectDescription(String effectDescription) {
        this.effectDescription = effectDescription;
    }
    
    public int getEffectDuration() {
        return effectDuration;
    }
    
    public void setEffectDuration(int effectDuration) {
        this.effectDuration = effectDuration;
    }
    
    public boolean isInterruptible() {
        return interruptible;
    }
    
    public void setInterruptible(boolean interruptible) {
        this.interruptible = interruptible;
    }
    
    public boolean isAvailable() {
        return available;
    }
    
    public void setAvailable(boolean available) {
        this.available = available;
    }
    
    public boolean isEnabled() {
        return enabled;
    }
    
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
}
